#!/usr/bin/python
# -*- coding: utf-8 -*-

import Ice, IceStorm, IceGrid
import sys, os, thread

try:
    HOME = os.environ['FIPA']
except KeyError:
    print 'FIPA environment variable is not currently defined.'
    sys.exit(0)

SLICE = os.path.join(HOME, 'slice')
FILE1 = os.path.join(SLICE, 'FIPA.ice')
FILE2 = os.path.join(HOME, 'test', 'Spammer.ice')
Ice.loadSlice('--all -I/usr/share/Ice/slice', ['-I' + SLICE, FILE1, FILE2])

import FIPA
import Test

class AgentI (FIPA.Agent):

    def __init__ (self, name, adapter):
        self.__name = name
        self.__state = FIPA.AgentState.Initiated
        self.__adapter = adapter
        self._proxies = {}
        self.__destroyed = False
        self.__mutex = thread.allocate_lock()

        # Well-known services.
        self._proxies['AMS'] = FIPA.AMSPrx.checkedCast(
            adapter.getCommunicator().stringToProxy('AMS'))
        self._proxies['DF'] = FIPA.DFPrx.checkedCast(
            adapter.getCommunicator().stringToProxy('DF'))
        self._proxies['MTS'] = FIPA.MTSPrx.checkedCast(
            adapter.getCommunicator().stringToProxy('MTS'))

        self._proxies['self'] = FIPA.AgentPrx.uncheckedCast(adapter.createIndirectProxy(self.__name))

        # Register with the AMS and DF.
        try:
            self._proxies['AMS'].register(self._proxies['self'])
        except FIPA.AgentExists, ex:
            print ex
            return

        try:
            self._proxies['DF'].register(FIPA.DfAgentDescription(self._proxies['self']))
            # Subscribe with the DF.
            self._proxies['DF'].subscribe(self._proxies['self'])
        except FIPA.AgentExists, ex:
            print ex
            pass
        except FIPA.AlreadySubscribed, ex:
            print ex
            pass

    # FIPA.Agent setState()
    def setState (self, state, curr = None):
        self.__mutex.acquire()
        self.__state = state
        self.__mutex.release()

    # FIPA.Agent getState()
    def getState (self, curr = None):
        return self.__state

    # FIPA.Agent receiveMessage()
    def receiveMessage (self, m, curr):
        #print self._proxies['self'].ice_toString() + ' received a message from: ' + m.env.frm.ice_toString() + ' with content: ' + m.payload.content
        
        # FOR TESTING PURPOSES.
        if m.payload.content == 'beginning':
            query = IceGrid.QueryPrx.uncheckedCast(curr.adapter.getCommunicator().stringToProxy('FIPA/Query'))
            sniffer = Test.SnifferPrx.checkedCast(query.findObjectById(curr.adapter.getCommunicator().stringToIdentity('Sniffer')))
            sniffer.beginTest('user')

        if m.payload.content == 'end':
            query = IceGrid.QueryPrx.uncheckedCast(curr.adapter.getCommunicator().stringToProxy('FIPA/Query'))
            sniffer = Test.SnifferPrx.checkedCast(query.findObjectById(curr.adapter.getCommunicator().stringToIdentity('Sniffer')))
            sniffer.endTest('user')

    # FIPA.Agent dfAdv()
    # Get the notification of a new event in the DF.
    # Example: agent x registered its description with the DF.
    def dfAdv (self, act, desc, curr = None):
        #print str(desc.name.ice_getIdentity().name) + ' did a ' + str(act) + ' with the DF.' 
        pass

    # FIPA.Agent destroy()
    def destroy (self, curr):
        self.__mutex.acquire()
        if self.__destroyed:
            raise Ice.ObjectNotExistException
        self.__destroyed = True

        # Unsubscribe with the DF.
        self._proxies['DF'].unsubscribe(
            FIPA.AgentPrx.uncheckedCast(curr.adapter.createIndirectProxy(curr.id)))
        # Deregister with the DF and the AMS.
        self._proxies['DF'].deregister(curr.id)
        self._proxies['AMS'].deregister(curr.id)

        # Remove the servant from the object adapter.
        curr.adapter.remove(curr.id)
        self.__mutex.release()

    def isZombie (self):
        return self.__destroyed
